package com.whcoding.test.common.encrypt;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @program: spring-boot-learning
 * @description:
 * 1.RSA密钥对生成：http://web.chacuo.net/netrsakeypair
 * 2.在线加密解密：http://encode.chahuo.com/
 * RSA算法是一种非对称加密算法，RSA 加密主要有这么几步：生成密钥对、公开公钥、公钥加密私钥解密、私钥加密公钥解密。
 * @author: whcoding
 * @create: 2022-05-25 13:56
 **/
public class RSAUtil {
	private static final String CHARSET_NAME = "utf-8";
	private static final String TYPE = "RSA";

	/**
	 * RSA公钥加密
	 *
	 * @param str       加密字符串
	 * @param publicKey 公钥
	 * @return 密文
	 * @throws Exception 加密过程中的异常信息
	 */
	public static String encrypt(String str, String publicKey) throws Exception {
		//base64编码的公钥
		byte[] decoded = Base64.decodeBase64(publicKey);
		RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(TYPE).generatePublic(new X509EncodedKeySpec(decoded));
		//RSA加密
		Cipher cipher = Cipher.getInstance(TYPE);
		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
		String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(CHARSET_NAME)));
		return outStr;
	}

	/**
	 * RSA私钥解密
	 *
	 * @param str        加密字符串
	 * @param privateKey 私钥
	 * @return 铭文
	 * @throws Exception 解密过程中的异常信息
	 */
	public static String decrypt(String str, String privateKey) throws Exception {
		//64位解码加密后的字符串
		byte[] inputByte = Base64.decodeBase64(str.getBytes(CHARSET_NAME));
		//base64编码的私钥
		byte[] decoded = Base64.decodeBase64(privateKey);
		RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(TYPE).generatePrivate(new PKCS8EncodedKeySpec(decoded));
		//RSA解密
		Cipher cipher = Cipher.getInstance(TYPE);
		cipher.init(Cipher.DECRYPT_MODE, priKey);
		String outStr = new String(cipher.doFinal(inputByte));
		return outStr;
	}

	public static void main(String[] args) throws Exception {
		String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD3MMeVqQJt1hOoNjB8OKiP8a4fHr31m6jli/iXJt0JoOiXtr2uCxpsypN0C4pqaXa5TPEZnRhY1CDCWKz9avmB1qNJn3x/rJ4A6WACVJngSz+G9vHSKFqIlxHFDx7h91Y8safeo2K/3u7pb9jymzs2AATQNaqbI4hkKKMu9dBbNQIDAQAB";
		String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAPcwx5WpAm3WE6g2\n" +
				"MHw4qI/xrh8evfWbqOWL+Jcm3Qmg6Je2va4LGmzKk3QLimppdrlM8RmdGFjUIMJY\n" +
				"rP1q+YHWo0mffH+sngDpYAJUmeBLP4b28dIoWoiXEcUPHuH3Vjyxp96jYr/e7ulv\n" +
				"2PKbOzYABNA1qpsjiGQooy710Fs1AgMBAAECgYEA7JxYrz0UAicEseMNDhr93qss\n" +
				"TMWUd2EEjpUo4yZkNi879N0LO2mNZc2Sz2WsnKdO6ZhowGfLQlvq750KGZkoMeqs\n" +
				"oJUK73xuECEcQtXQruU2eje3g03tcnfFvbkOzwfsvgOnhL2ivwsnRyepYnIffZ+Q\n" +
				"lC2iVZCJNSCB1/eHW5ECQQD/AN/KvXZsGxYaQE6A7tJJ3hF7Fo61Ai0hi65ZJSZf\n" +
				"0TsiEKLUDog39OxNJ7Mp74v19pJK+bpkDkCXLMblrrhjAkEA+CgWvPLcXX7Vhtea\n" +
				"KHAGwAQj7FFVrY0lQqjA51Gqp0GZTTrXbrqpCw/rBVc3M4UXS7MLRcPqDpGrpkND\n" +
				"aU8VhwJASc7d95eZJDc+0YBVeJongbvmAWOJELk9iN0eLK1FCyzLWdPI3WoLYW7h\n" +
				"yn84K2Yrc5jXxR29JmK9rUQHmclVkwJBAPNohx0g7ov6q8EO29QMRmKz7PSQtwR7\n" +
				"rO+cjVKYJVbXnmJFdCjViJgkLffYG3o6cqY64bS1vXA67G4yDf5OpyMCQFSjbBCp\n" +
				"RvNJg9v1UNeCdrfu+Y3HcJVPoTJdfLlkOZDiKTpapHTzjTXKDpftLDp+recmg+aZ\n" +
				"WyajwiWGtjVTRxY=";
		String text = "hello world";
		String encodeText = encrypt(text, publicKey);
		System.out.println("加密后：" + encodeText);
		System.out.println("解密后：" + decrypt(encodeText, privateKey));
	}
}
